QUALITY-928: Orchestration unified stack — observer-parent restore (M3) - #14608
Draft
cephalonaut wants to merge 44 commits into
Draft
QUALITY-928: Orchestration unified stack — observer-parent restore (M3)#14608cephalonaut wants to merge 44 commits into
cephalonaut wants to merge 44 commits into
Conversation
Spec covers the unified two-PR stack approach (M1: core tracker + family stream; M2: pane path + transcript). Supersedes the Phase 0 interim approach. Key decisions documented: OrchestrationUnifiedStack single flag, viewer transcript authorization resolved (§9.1), parent session ACL propagation via warp-server PR #12252. Co-Authored-By: Oz <oz-agent@warp.dev>
- Retitle: now describes M1+M2 two-PR stack from master - §1: rewrite scope to M1/M2; note Phases 1-3 incremental roadmap superseded - §3: retitle to 'M1 — Core Tracker + Unified Stream'; replace Phase 0 client implementation descriptions with M1 implementation (tracker, family drain, classify_family_event, SessionLinked signal) - §4: replace 'two stacks' with north-star architecture diagram - §5/§6: update from 'blocks naive reuse' to 'drove the unified design' - §8: already updated (migration plan) - §10: rewrite deletion scorecard with M1/M2 framing - §11: update risks and validation to remove Phase 0/1/3 references; resolve include_self topology question Co-Authored-By: Oz <oz-agent@warp.dev>
…ck flag Introduce the unified child-tracking state machine that will become the sole entry point for orchestration child state on both owner and viewer sides (TECH QUALITY-928 §7.2), plus the dogfood feature flag that gates the M1 stack. `OrchestrationChildTracker::observe_child` classifies every discovery signal (Started, SessionLinked, Lifecycle, Seeded, Registered) into the four-step logic: tombstone drop, create-or-update placeholder, status write-through, claim-time metadata refetch, and pane materialization. The side effects that need broader streamer plumbing (placeholder creation, metadata fetch via AgentConversationsModel, pane path) are stubbed here and wired up by T2 and M2; the tracker's own state machine is complete and unit-tested. Co-Authored-By: Oz <oz-agent@warp.dev>
Add the unified family-stream fan-out behind FeatureFlag::OrchestrationUnifiedStack: - classify_family_event + FamilyEvent: classify one include_self ancestor SSE event into ParentSelf / ChildStarted / ChildSessionLinked / ChildLifecycle / Opaque relative to the parent's own self_run_id. - drain_family_events: routes discovery/session-link/lifecycle signals to OrchestrationChildTracker::observe_child, delivers ParentSelf inbox via the existing handle_event_batch (owner only), and dispatches cursor authority by mode (owner: local + server; viewer: local only). - Host an OrchestrationChildTracker in ConversationStreamState (owner) and OrchestratorStreamState (viewer), created lazily by the flag-on drain. - Gate the seven drain_sse_events / drain_ancestor_events call sites through drain_owner_events / drain_viewer_events dispatchers. Flag-off preserves the legacy per-conversation and ancestor drains unchanged. - Derive PartialEq/Eq on AgentRunEvent for classification tests; add cfg(test) accessors on the tracker for sibling-module drain tests. Tests: classify_family_event (all five variants + edge cases) and drain_family_events owner/viewer routing, inbox delivery, and viewer no-server-push cursor authority. Co-Authored-By: Oz <oz-agent@warp.dev>
…cleanup Sub-task A: the OrchestrationChildTracker now records the unified is_remote_child placeholder flavor (TECH QUALITY-928 §7.4) for every child it materializes in both owner and viewer mode. TrackedChild gains an is_remote_child marker (true for tracker-materialized placeholders, false for in-band children that own a real local conversation). Claim-time metadata fetches route through AgentConversationsModel::get_or_async_fetch_task_data (the shared fetch authority, §7.6 item 1); a synchronous cache hit resolves the placeholder inline, a miss resolves on a later re-drive. The real dispatch is compiled out of unit-test builds, which keep the dispatch-counter stand-in. Adds a viewer-mode unit test asserting the placeholder is is_remote_child and never is_viewing_shared_session. Sub-task B: no code changes required — FeatureFlag::OrchestrationViewerStreamer and FeatureFlag::OwnerOrchestrationAncestorStreamer never existed in the implementation (the shipped stack uses OrchestrationUnifiedStack + WaitForEventsParentRegistration), and the legacy viewer REST polling path (fetch_children / schedule_next_poll / maybe_kick_polling / apply_children_fetch) is already absent from OrchestrationViewerModel. Fixed a stale doc comment in terminal_pane.rs that referenced the removed apply_children_fetch. Co-Authored-By: Oz <oz-agent@warp.dev>
…_family_events When a child_agent_started (ChildStarted) or lifecycle event arrives in the flag-ON family drain (drain_family_events), ensure a local is_remote_child AIConversation placeholder exists for the child before routing the signal through the tracker. This makes the orchestration pill bar populate immediately for out-of-band (cloud) children, fixing QUALITY-928 M1. Previously observe_child delegated placeholder creation to an async AgentConversationsModel fetch that did not call back into the tracker on a cache miss, so ChildSpawned was never emitted and the pill bar never rendered the child. The fix adds two methods to OrchestrationEventStreamer: - ensure_remote_child_placeholder: idempotency-guarded async metadata fetch - finish_remote_child_placeholder: creates the AIConversation from fetched metadata, marks it is_remote_child, assigns the run_id, and persists In drain_family_events, ChildStarted and ChildLifecycle (backstop) both call ensure_remote_child_placeholder when mode == Owner before the existing tracker.observe_child call. Debug logging added for all child event variants. Co-Authored-By: Oz <oz-agent@warp.dev>
Bug 1: Status badges not updating - In OrchestrationChildTracker::apply_lifecycle, add history model write-through when a lifecycle event arrives for a tracked child. Looks up the child conversation by run_id via conversation_id_for_agent_id, then calls update_conversation_status so the pill bar badge reflects the lifecycle transition immediately. - Previously the comment said 'T2: also write status through BlocklistAIHistoryModel' but the implementation was a stub. Bug 2: Clicking child pill shows zero state - In PaneGroup::attempt_remote_child_hydration, for the LiveAttach case, also call attach_execution_session_to_ambient_pane after apply_existing_ambient_task_to_pane. - Previously enter_viewing_existing_session set AgentRunning status but never emitted ExecutionSessionReady, leaving the pane disconnected from the live session and showing blank content. Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
Mechanical M1 terminology rename: - ChildTrackingMode -> OrchestrationEventConsumer - Owner -> Primary - Viewer -> Observer This type describes family-event consumption and cursor responsibility only (Primary delivers parent-self + server cursor; Observer drops parent-self and persists local cursor only). No behavior change. Co-Authored-By: Oz <oz-agent@warp.dev>
Remove references to TECH QUALITY-928 section numbers, M1/M2/T1/T2 milestone labels, legacy type names, and speculative future-work prose from doc comments in orchestration_child_tracker.rs, orchestration_event_streamer.rs, and mod.rs. No logic changes. Co-Authored-By: Oz <oz-agent@warp.dev>
When spawn_metadata_fetch gets a cache miss, the guard stays set and later re-drives from Lifecycle/Started signals return early at the guard check -- even after the async fetch completes and the cache is warm. The task never gets picked up by the tracker. Fix: when the guard is already set, poll AgentConversationsModel once to check if the fetch completed. If the cache is warm, clear the guard and call apply_seeded. If still in flight, AgentConversationsModel's own in-flight dedup suppresses a redundant network request. Co-Authored-By: Oz <oz-agent@warp.dev>
cephalonaut
force-pushed
the
matthew/orch-unified-m2
branch
from
July 31, 2026 22:11
62ec14f to
1030741
Compare
cephalonaut
force-pushed
the
matthew/orch-unified-m3
branch
4 times, most recently
from
August 1, 2026 02:18
c07c191 to
87d6305
Compare
…drain In drain_family_events, only parent_self_events were passed to handle_event_batch. convert_lifecycle_events (inside handle_event_batch) filters by run_id != self_run_id, so it needs child events to inject lifecycle notifications into OrchestrationEventService for the parent conversation. Without this, the parent BlocklistAIController never receives child lifecycle events, causing a regression for local parents with local or remote children. Fix: collect child lifecycle events during the drain loop and extend parent_self_events before the handle_event_batch call in Primary mode. Co-Authored-By: Oz <oz-agent@warp.dev>
cephalonaut
force-pushed
the
matthew/orch-unified-m2
branch
from
August 1, 2026 03:06
74d38ec to
c902025
Compare
cephalonaut
force-pushed
the
matthew/orch-unified-m3
branch
from
August 1, 2026 03:07
87d6305 to
0646657
Compare
…older unification - Rewrite orchestration_child_tracker.rs module doc in plain language: guides children from discovery to pane materialization - Add TODO documenting intent to unify is_remote_child and is_viewing_shared_session into a single is_remote_placeholder flag Co-Authored-By: Oz <oz-agent@warp.dev>
cephalonaut
force-pushed
the
matthew/orch-unified-m2
branch
from
August 1, 2026 05:12
c902025 to
9c46577
Compare
cephalonaut
force-pushed
the
matthew/orch-unified-m3
branch
2 times, most recently
from
August 1, 2026 05:22
33eae80 to
1bd4310
Compare
…ntConsumer The conversation_id field in TrackedChild was never read — all actual conversation lookups use history.conversation_id_for_agent_id(run_id). OrchestrationEventConsumer existed solely to ferry conversation IDs into TrackedChild. Both are now removed. - Remove OrchestrationEventConsumer enum (Primary/Observer distinction is already captured by FamilyDrainMode in the streamer) - Remove conversation_id from TrackedChild - Simplify OrchestrationChildTracker::new() to take only parent_task_id - Remove placeholder_conversation_id() method - Simplify ChildSignal::Registered to a unit variant Co-Authored-By: Oz <oz-agent@warp.dev>
cephalonaut
force-pushed
the
matthew/orch-unified-m2
branch
from
August 1, 2026 15:31
5ffcb5e to
96119ad
Compare
cephalonaut
force-pushed
the
matthew/orch-unified-m3
branch
2 times, most recently
from
August 1, 2026 15:42
53051b7 to
71bfd7c
Compare
Consolidate the TECH spec so M1's document stands alone and reflects the final simplified architecture: - Rename owner/viewer to Primary/Observer throughout - Add ChildPaneOrigin, TaskOwnership, ConversationAccess definitions - Update placeholder flavor descriptions with current field names - Update tracker step descriptions to match simplified implementation (no conversation_id in TrackedChild, no OrchestrationEventConsumer) - Update pane path §4.3 with capability-separation clarification - Update cursor and delivery path descriptions to use Primary/Observer - Update north-star diagram labels Co-Authored-By: Oz <oz-agent@warp.dev>
Introduce a mode-agnostic child pane dispatch decision that returns the same result for owner and viewer given identical task state. This is the unified replacement for decide_remote_child_hydration_action; callers are wired up in a follow-up task. Co-Authored-By: Oz <oz-agent@warp.dev>
…iedStack Restore flag-OFF paths so M2's unified child pane dispatch sits safely behind FeatureFlag::OrchestrationUnifiedStack (dogfood-only). - Restore RemoteChildHydrationAction enum, decide_remote_child_hydration_action, hydrate_task_backed_hidden_child_pane, attempt_remote_child_hydration, hydrate_remote_child_transcript_in_place, attach_ambient_session_and_maybe_tombstone, and process_pending_remote_child_hydrations as flag-OFF paths in hydration.rs. - Restore ensure_shared_session_viewer_child_pane as flag-OFF path in restoration.rs. - Restore pending_remote_child_hydrations field on PaneGroup and its drain call in handle_pending_ambient_restoration_event. - Flag-dispatch in create_hidden_child_agent_pane: flag-ON routes through materialize_child_placeholder_pane (M2 unified path); flag-OFF routes through the original hydrate_task_backed_hidden_child_pane / viewer loading placeholder. - Flag-dispatch in EnsureSharedSessionViewerChildPane handler: flag-ON calls attach_child_session(Viewer); flag-OFF calls ensure_shared_session_viewer_child_pane. - Add OrchestrationUnifiedStack override to tests that exercise flag-ON behavior. Co-Authored-By: Oz <oz-agent@warp.dev>
Carry the M1 zero-state pane fix into M2's unified owner materialization path by attaching the known shared session after binding the ambient task. Co-Authored-By: Oz <oz-agent@warp.dev>
…estigation Instruments the full status-badge and pane-click failure paths to trace both bugs without changing behavior: Status path (Bug 1): - drain_family_events: ChildStarted / ChildLifecycle / ChildSessionLinked events (INFO) - ensure_remote_child_placeholder: entry / skip-existing / fetch-start (INFO) - finish_remote_child_placeholder: success / failure / skip / created (INFO) - apply_lifecycle: entry tracker_known/fetch_in_flight, history-lookup result, update_conversation_status before/after, emit ChildStatusChanged (INFO) Pane path (Bug 2): - create_hidden_child_agent_pane: entry flags + feature flag state (INFO) - materialize_child_placeholder_pane: idempotent-skip / entry / task-detail (INFO) - materialize_owner_child_pane: match-arm taken / Pending (INFO) - attach_child_session: entry / owner pane-not-found / task_id / result (INFO) - attach_execution_session_to_ambient_pane: entry has_ambient_model / via-ambient-model-ok / no-terminal-manager / non-viewer-manager / via-viewer-ok (INFO) No behavioral changes. All log lines share the [orchestration-unified-debug] prefix. Co-Authored-By: Oz <oz-agent@warp.dev>
Root causes (confirmed by [orchestration-unified-debug] log): Bug 1 (status badges): apply_started never inserted a TrackedChild into children[], so every subsequent Lifecycle call saw tracker_known=false and exited immediately. Fix: insert a TrackedChild eagerly in apply_started (before the async metadata fetch) so Lifecycle and SessionLinked signals see the child and call update_conversation_status. stamp_conversation_id_for_run then patches the stand-in conversation_id once finish_remote_child_placeholder creates the real AIConversation. Bug 2 (zero-state pane) - two sub-causes: 2a (running child): AgentConversationsModel had stale Queued/Inactive task data from the initial discovery fetch; the linked session_id was never injected, so decide_child_pane_materialization returned Pending. Fix: on ChildSessionLinked in drain, call update_task_as_running_with_session to mark the cached task InProgress + is_sandbox_running=true + session_id so the next pill click returns AttachLive. 2b (completed child): task data still showed Queued after Succeeded; no conversation token was present so LoadTranscript was never returned. Fix: on terminal ChildLifecycle, call evict_and_refetch_task to drop the stale cache entry and start a fresh fetch. The Pending arm of materialize_owner_child_pane now registers in pending_remote_child_hydrations so process_pending_remote_child_hydrations re-drives with the fresh data (AttachLive or LoadTranscript) when TasksUpdated fires. Co-Authored-By: Oz <oz-agent@warp.dev>
Owner-side Pending children now use the existing child loading presentation instead of the generic cloud-agent composing zero state. When a session becomes attachable, discard the loading pane and construct a fully initialized ambient shared-session viewer before swapping it into the prior visible anchor. This mirrors normal ambient restoration and avoids rendering agent input while a deferred pane has transient unbounded constraints. Completed children keep the loading pane until the transcript fetch and placeholder merge succeed, then switch the terminal model to read-only ambient transcript state before restoring content. This makes Pending-to-LoadTranscript safe without exposing the composing input. Flag-off behavior remains unchanged. No flex assertions or terminal input layout code are modified. Co-Authored-By: Oz <oz-agent@warp.dev>
AgentViewController previously derived EnteredAgentView.is_new solely from exchange_count == 0. Existing remote-child placeholders are often empty while restoring or before their first streamed exchange, so they were misclassified as brand-new cloud conversations and received the generic New Oz cloud agent conversation zero-state header. Under OrchestrationUnifiedStack, preserve the existing remote-child identity and emit is_new=false. New cloud conversations and flag-off behavior are unchanged. Co-Authored-By: Oz <oz-agent@warp.dev>
Completed owner-side remote children were forced into ViewingAmbientConversation transcript state, which makes TerminalModel permanently read-only and suppresses the footer even when ownership resolves to an editable Oz follow-up. Route owner completed hydration through the established restored ambient cloud-mode pane path after merging the canonical child placeholder. Preserve owner mode by explicitly clearing passive shared-session state; ownership then chooses NotShared plus the normal continuation input, while passive viewers retain the read-only transcript path. Running child restore remains on the active shared-session viewer path. The existing remote-child is_new=false fix remains unchanged. Co-Authored-By: Oz <oz-agent@warp.dev>
Completed child restoration used generic replace_pane, which requires the loading pane to be present in the layout tree. Persisted child panes are restored off-tree, so the fully restored replacement was immediately cleaned up after tree replacement failed and the original loading pane remained forever. Use the child-specific lifecycle instead: capture any visible swap anchor, discard the loading child, construct and restore the owner ambient continuation pane, attach it off-tree, update child_agent_panes, and re-swap only when needed. Owner continuation, passive viewer read-only behavior, pending safety, and existing-child header semantics remain intact. Co-Authored-By: Oz <oz-agent@warp.dev>
Trace canonical conversation/root identity, follow-up ambient task/session state, shared-session load mode and replay suppression, shared Init conversation resolution, and incoming CreateTask vs current root identity. No behavior changes and no prompt/message/token content logging. Co-Authored-By: Oz <oz-agent@warp.dev>
AppendFollowupScrollback previously relied solely on AgentConversationReplayStarted to initialize terminal and controller replay gates. Some follow-up sessions deliver existing transcript Init/CreateTask events before that marker, allowing a server-backed root to be treated as an optimistic task and corrupting the restored conversation. Initialize both replay-gate halves synchronously when the append-mode EventLoop is created. The existing request-aware check still permits unseen live request IDs, and AgentConversationReplayEnded clears the gate normally. Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
Remove stale tracker dead-code annotation, avoid treating Unspecified lifecycle events as terminal for task refetch, and document follow-up cleanup for duplicate metadata fetches and child registries.\n\nCo-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
Remove is_durable_observer_parent from M2 so the observer-parent restore
feature can land as a separate PR. Under flag-ON, a terminal owned cloud
run viewed as an observer now falls through to a fresh compose pane on
restart instead of the durable restore path — identical to the flag-OFF
and pre-M2 baseline behavior, so this is a deferral not a regression.
Removes:
- AgentConversationData.is_durable_observer_parent field (persistence)
- AIConversation.is_durable_observer_parent field + getter/setter
- BlocklistAIHistoryModel::{mark_conversation_as_durable_observer_parent,
restore_durable_observer_parent_for_task}
- Eager-hydration branch in conversation_loader.rs
- Durable-parent gate in ambient_pane_restoration.rs
- TaskOwnership::Owned ownership check in OrchestrationViewerModel
- restore_durable_observer_parent_for_task call in terminal_manager.rs
- Corresponding tests (moved to M3 branch)
Co-Authored-By: Oz <oz-agent@warp.dev>
current_root_id and current_root_has_server_data were declared in the CreateTask action handler alongside a log::info! that referenced them. The log statement was removed by the debug cleanup pass but the variable declarations were left behind. Co-Authored-By: Oz <oz-agent@warp.dev>
Restore the original M1 comment; the rewrite was a side-effect of the is_durable_observer_parent extraction. Co-Authored-By: Oz <oz-agent@warp.dev>
Co-Authored-By: Oz <oz-agent@warp.dev>
#2: Remove empty if-block for is_existing_child_placeholder in controller.rs #3: Remove dead selected_conversation_id/root_identity bindings in shared_session.rs #4: Simplify ensure_remote_child_conversation comment to focus on idempotence #10/#11: Update tracker field comments to use Primary/Observer terminology and explain when None Co-Authored-By: Oz <oz-agent@warp.dev>
- Remove fetch_in_flight in apply_lifecycle (code now calls apply_started directly) - Simplify Pending arm pane creation to is_none() check (pane_id was unused) - Remove root_task binding in hydrate_owner_child_transcript (never referenced) - Remove has_ambient_model binding in attach_execution_session_to_ambient_pane Co-Authored-By: Oz <oz-agent@warp.dev>
#8 (M2-specific): Remove stamp_conversation_id_for_run calls from finish_remote_child_placeholder. The function is no longer on the tracker since conversation_id was removed from TrackedChild. #9: OVM's flag-ON path now uses AgentConversationsModel::get_or_async_fetch_task_data instead of a direct ai_client fetch + cache_task_data. A cache hit calls register_child immediately; a miss adds to pending_task_ids_for_discovery and resolves on the next TasksUpdated event via drain_pending_task_discoveries. Also removes cache_task_data from ACM (no longer called anywhere) and removes the now-redundant cache_task_data call from materialize_viewer_child_pane_from_task (task data is already in ACM). Co-Authored-By: Oz <oz-agent@warp.dev>
cephalonaut
force-pushed
the
matthew/orch-unified-m2
branch
from
August 1, 2026 17:26
8dd85d8 to
6c23d40
Compare
…ud runs When a user owns a /cloud-agent run but opens it via the shared-session viewer path (e.g. through a shared link), this PR makes that pane restore durably across restarts instead of opening a fresh compose pane. What: - AgentConversationData.is_durable_observer_parent: bool (persisted marker) - mark_conversation_as_durable_observer_parent: stamps marker + task_id on the parent placeholder when TaskOwnership::Owned is confirmed by OVM - restore_durable_observer_parent_for_task: re-attaches the eagerly-hydrated conversation to the restored ambient pane before shared-session replay - Eager hydration in conversation_loader.rs: durable observer parents load at startup with their event cursor, excluded from navigation history - Durable-parent restore in ambient_pane_restoration.rs: RestoreOrNavigate installs the persisted conversation in cloud-mode instead of fresh compose Note: this could alternatively be replaced by making is_viewing_shared_session persistent for all viewer conversations (not just owned ones), which would be simpler. This PR keeps the feature isolated for independent evaluation. Co-Authored-By: Oz <oz-agent@warp.dev>
cephalonaut
force-pushed
the
matthew/orch-unified-m3
branch
from
August 1, 2026 17:26
71bfd7c to
4f2a186
Compare
cephalonaut
force-pushed
the
matthew/orch-unified-m2
branch
from
August 2, 2026 20:12
081761c to
53b8105
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds durable restore for owned cloud runs that are observed via the shared-session viewer path (QUALITY-928). Stacks on M2.
What
AgentConversationData.is_durable_observer_parent: bool— persisted marker that survives restart.mark_conversation_as_durable_observer_parentonBlocklistAIHistoryModel— stamps the marker and task ID on the parent placeholder whenTaskOwnership::Ownedis confirmed.restore_durable_observer_parent_for_task— re-attaches the eagerly-hydrated conversation to the restored ambient pane before shared-session replay.conversation_loader.rs— durable observer parents load at startup with their event cursor, excluded from navigation history.ambient_pane_restoration.rs— whenRestoreOrNavigateToConversationfires for a terminal owned run, installs the persisted conversation in cloud-mode presentation instead of opening a fresh compose pane.Why
Before this, owned cloud runs observed via a shared link always restored as a fresh compose pane on restart — the observer cursor and child hierarchy were not preserved. This PR makes that restore durable.
Alternative: making
is_viewing_shared_sessionpersistent for all viewer conversations (not just owned ones) would achieve the same result more simply and extend the behavior to collaborators too. This PR keeps the feature isolated so that decision can be made independently.Linked Issue
QUALITY-928
Testing
test_durable_observer_parent_marker_is_written_before_shutdown— marker is persisted andtask_idis stamped.historical_durable_observer_parent_restores_cursor_and_child_hierarchy— cursor and child hierarchy survive a history-model cold-start.running_durable_observer_snapshot_selects_shared_session_reattach— running observer pane restores into a live session attach.terminal_durable_observer_snapshot_restores_existing_parent_and_children— terminal observer pane restores into cloud-mode with existing conversation and child hierarchy.I have manually tested my changes locally with
./script/runAgent Mode